package com.maschinenstuermer.profiler.model;

import java.util.List;

import com.maschinenstuermer.profiler.model.impl.CompositeInvocation;
import com.maschinenstuermer.profiler.model.impl.Invocation;
import com.maschinenstuermer.profiler.model.impl.MethodInvocation;
import com.maschinenstuermer.profiler.model.impl.Metrics;
import com.maschinenstuermer.profiler.model.impl.ModelVisitor;
import com.maschinenstuermer.profiler.model.impl.ProfiledMethod;
import com.maschinenstuermer.profiler.model.impl.SqlStatementExecution;
import com.maschinenstuermer.profiler.model.impl.ThreadCallStack;
import com.maschinenstuermer.profiler.model.impl.Trace;
import com.maschinenstuermer.profiler.model.impl.Transaction;

public class PostProcessModelVisitor implements ModelVisitor {
	public void visit(Trace trace) {
		List<ThreadCallStack> threadCallStacks = trace.getThreadCallStacks();
		for (ThreadCallStack threadCallStack : threadCallStacks) {
			final Metrics metrics = threadCallStack.getMetrics();
			for (final Invocation invocation : threadCallStack.getChildren()) {
				metrics.add(invocation.getMetrics());
			}
		}
		for (final ThreadCallStack threadCallStack : threadCallStacks) {
			threadCallStack.accept(this);
		}
	}

	public void visit(final ThreadCallStack threadCallStack) {
		for (final Invocation invocation : threadCallStack.getChildren()) {
			invocation.accept(this);
		}
	}

	public void visit(final MethodInvocation methodInvocation) {
		final ProfiledMethod method = methodInvocation.getMethod();
		method.getMetrics().add(methodInvocation.getMetrics());
		
		visit((Invocation) methodInvocation);
		visit((CompositeInvocation) methodInvocation);
	}

	public void visit(final Transaction transaction) {
		visit((Invocation) transaction);
		visit((CompositeInvocation) transaction);
	}

	public void visit(final SqlStatementExecution sqlStatementExecution) {		
		visit((Invocation) sqlStatementExecution);
	}

	public void visit(final CompositeInvocation compositeInvocation) {
		for (final Invocation invocation : compositeInvocation.getChildren()) {
			invocation.accept(this);
		}
	}
	
	public void visit(Invocation invocation) {
	}	
}
